package plp.orientadaObjetos2.comando;

import plp.orientadaObjetos1.comando.ChamadaProcedimento;
import plp.orientadaObjetos1.comando.New;
import plp.orientadaObjetos1.comando.Procedimento;
import plp.orientadaObjetos1.excecao.declaracao.ClasseJaDeclaradaException;
import plp.orientadaObjetos1.excecao.declaracao.ClasseNaoDeclaradaException;
import plp.orientadaObjetos1.excecao.declaracao.ObjetoJaDeclaradoException;
import plp.orientadaObjetos1.excecao.declaracao.ObjetoNaoDeclaradoException;
import plp.orientadaObjetos1.excecao.declaracao.ProcedimentoJaDeclaradoException;
import plp.orientadaObjetos1.excecao.declaracao.ProcedimentoNaoDeclaradoException;
import plp.orientadaObjetos1.excecao.declaracao.VariavelJaDeclaradaException;
import plp.orientadaObjetos1.excecao.declaracao.VariavelNaoDeclaradaException;
import plp.orientadaObjetos1.excecao.execucao.EntradaInvalidaException;
import plp.orientadaObjetos1.expressao.ListaExpressao;
import plp.orientadaObjetos1.expressao.leftExpression.Id;
import plp.orientadaObjetos1.expressao.leftExpression.LeftExpression;
import plp.orientadaObjetos1.expressao.valor.ValorRef;
import plp.orientadaObjetos1.memoria.colecao.ListaValor;
import plp.orientadaObjetos2.declaracao.ConstrutorNaoDeclaradoException;
import plp.orientadaObjetos2.declaracao.DefClasseOO2;
import plp.orientadaObjetos2.excecao.interfaces.InterfaceJaDeclaradaException;
import plp.orientadaObjetos2.memoria.AmbienteExecucaoOO2;
import plp.orientadaObjetos2.memoria.ContextoExecucaoOO2;

public class NewOO2 extends New{
	
	private ListaExpressao parametrosReais;
	
	public NewOO2(LeftExpression av, Id classe, ListaExpressao parametrosReais) {
		super(av, classe);
		this.parametrosReais = parametrosReais;
	}

	@Override
	public AmbienteExecucaoOO2 executar(AmbienteExecucaoOO2 ambiente) 
		throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException,
		ClasseJaDeclaradaException, ClasseNaoDeclaradaException,
		ObjetoJaDeclaradoException,ObjetoNaoDeclaradoException, 
		ProcedimentoJaDeclaradoException, ProcedimentoNaoDeclaradoException, EntradaInvalidaException, 
		ConstrutorNaoDeclaradoException, InterfaceJaDeclaradaException {

		super.executar(ambiente);
		
		DefClasseOO2 defClasse = (DefClasseOO2) ambiente.getDefClasse( getClasse() );
		Procedimento metodo = defClasse.getConstrutor().getProcedimento();
		AmbienteExecucaoOO2 aux = new ContextoExecucaoOO2(ambiente); 

		ValorRef vr = (ValorRef) getAv().avaliar(ambiente);
		aux.changeValor(new Id("this"), vr);
		aux.changeValor(new Id("super"), vr);

		ListaValor valoresDosParametros = parametrosReais.avaliar(ambiente);
		new ChamadaProcedimento(metodo, parametrosReais, valoresDosParametros).executar(aux);

		return ambiente;
	}

}
